#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<fcntl.h>

void recv_file(int c,char *s,char *filename)
{
    if(s==NULL||filename==NULL)
    {
        printf("请输入文件名称\n");
        return ;
    }
    send(c,s,strlen(s),0);

    char buff[128]={0};
    int n=recv(c,buff,127,0);

    if(n<=0)
    {
        printf("ser close\n");
        return ;
    }

    if(strncmp(buff,"ok#",3)!=0)
    {
        printf("文件不存或无法下载\n");
        return ;
    }

    int filesize=atoi(buff+3);

    int fd=open(s,O_WRONLY|O_CREAT,0600);
    if(filesize==0||fd==-1)
    {
        send(c,"err",3,0);
        close(fd);
        return;
    }
    
    if(fd==-1)
    {
        send(c,"err",3,0);
        return;
    }
    
    send(c,"ok",2,0);
    
    char data[1024]={0};
    int curr_size=0;
    float f=0.0;
    int num=0;
    while(1)
    {
        num=recv(c,data,1024,0);
        if(num<=0)
        {
            printf("服务器关闭\n");
            break;
        }
        write(fd,data,num);
        curr_size+=num;
        f=curr_size*100.0/filesize;
        printf("down %s:%.2f%%\r",s,f);
        fflush(stdout);
        if(curr_size>=filesize)
        {
            break;
        }
    }
    printf("\n");
    close(fd);
}




int connect_ser()
{
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==-1)
    {
        return -1;
    }

   struct sockaddr_in saddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(6000);
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");


    int res= connect(sockfd,(struct  sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        return  -1;
    }

    return sockfd; 

}


char *get_cmd(char buff[],char *myargv[])
{
    if(buff==NULL||myargv==NULL)
    {
        return NULL;
    }

    int i=0;
    char *s=strtok(buff," ");
    while(s!=NULL)
    {
        myargv[i++]=s;
        s=strtok(NULL," ");
    }

    return myargv[0];
}

void send_file(int c,char *s,char *name)
{
    if(s==NULL||name==NULL)
    {
        send(c,"err",3,0);
        return;
    }
    send(c,s,strlen(s),0);
    int fd=open(name,O_RDONLY);
    if(fd==-1)
    {
        printf("file not exist\n");
        return;
    }
    char buff[128]={0};
    int r= recv(c,buff,127,0); 
     if(r<=0)
     {
         return;
     }   
     if(strcmp(buff,"err")==0)
     {
         printf("dsdsd\n");
         return;
     }
    if(strcmp(buff,"ok")!=0)
    {
        printf("aaa\n");
        return;
    }
    int n=lseek(fd,0,SEEK_END);
    lseek(fd,0,SEEK_SET);
    memset(buff,0,128);
    sprintf(buff,"ok#%d",n);
    send(c,buff,strlen(buff),0);
    memset(buff,0,128);
    int m=recv(c,buff,127,0);
    if(m<=0)
    {
        close(fd);
        return;
    }
    if(strcmp(buff,"ok#")!=0)
    {
        close(fd);
        return;
    }
    char data[1024]={0};
    int num=0;
    int curr_size=0;
    float f=0.0;
    while((num=read(fd,data,1024))>0)
    {
        printf("sasasda\n");
        send(c,data,num,0);
        curr_size+=num;
        f=curr_size*100.0/n;
        printf("down %s:%.2f%%\r",s,f);
        fflush(stdout);
    }
    close(fd);
    printf("down file finish\n");
}

int main()
{
    int sockfd=connect_ser();
    if(sockfd==-1)
    {
        printf("connect ser failed\n");
        exit(0);
    }
    while(1)
    {
        char buff[128]={0};//从键盘获取数据
        printf("connect 127.0.0.1>>");
        fflush(stdout);

        fgets(buff,128,stdin);
        buff[strlen(buff)-1]=0;//将最后一位\n去掉

        char send_buff[128]={0};
        strcpy(send_buff,buff);//将buff内容备份，因为我们在将buff拆分后，不用再组合

        //判断buff中放入的是啥

        char* myargv[10]={0};//用来存放解析之后的命令和参数

        char *cmd=get_cmd(buff,myargv);//将buff内容分割
        
        if(cmd==NULL)
        {
            continue;
        }

        if(strcmp(cmd,"end")==0)
        {
            break;
        }
        else if(strcmp(cmd,"get")==0)
        {
           recv_file(sockfd,send_buff,myargv[1]);
        }
        else if(strcmp(cmd,"up")==0)
        {
            send_file(sockfd,send_buff,myargv[1]);
        }
        else
        {
            send(sockfd,send_buff,strlen(send_buff),0);
            
            char recv_buff[1024]={0};
            int res=recv(sockfd,recv_buff,1023,0);

            if(res<=0)
            {
                printf("ser close\n");
                break;
            }
            if(strncmp(recv_buff,"OK#",3)==0)
            {
                printf("%s\n",recv_buff+3);
            }
            else
            {
                printf("cmd run  err\n");
            }
        }
        

    }
    close(sockfd);
}





